Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rails 5.0.0beta2: Weird behaviour of config belongs_to_required_by_default #23589

Closed
nflorentin opened this issue Feb 10, 2016 · 26 comments
Closed

Comments

@nflorentin
Copy link

I'm facing a weird issue with the new config belongs_to_required_by_default

In first app

created with rails 5.0.0beta1 and updated to 5.0.0beta2, I have in initializers/active_record_belongs_to_required_by_default.rb:
Rails.application.config.active_record.belongs_to_required_by_default = true

In rails console:

> Rails.application.config.active_record.belongs_to_required_by_default
=> true
> ActiveRecord::Base.belongs_to_required_by_default
=> nil
> User.belongs_to_required_by_default
=> nil

If I replace Rails.application.config.active_record.belongs_to_required_by_default = true with ActiveRecord::Base.belongs_to_required_by_default = true, all work as expected and I get my associations validated.

After the replacement, I get in console:

> Rails.application.config.active_record.belongs_to_required_by_default
=> nil
> ActiveRecord::Base.belongs_to_required_by_default
=> true
> User.belongs_to_required_by_default
=> true

In second app

freshly created with rails 5.0.0beta2, with Rails.application.config.active_record.belongs_to_required_by_default = true.

In rails console:

> Rails.application.config.active_record.belongs_to_required_by_default
=> true
> ActiveRecord::Base.belongs_to_required_by_default
=> true
> User.belongs_to_required_by_default
=> true
@nflorentin nflorentin changed the title Weird behaviour of config belongs_to_required_by_default 5.0.0beta2: Weird behaviour of config belongs_to_required_by_default Feb 10, 2016
@nflorentin nflorentin changed the title 5.0.0beta2: Weird behaviour of config belongs_to_required_by_default Rails 5.0.0beta2: Weird behaviour of config belongs_to_required_by_default Feb 10, 2016
@nflorentin
Copy link
Author

Just find that installing friendly_id, only adding it in gemfile, was the reason of this issue.
I think I can close this one.
I opened an issue on friendly_id repo.

@arokettu
Copy link

Rails 5.0.0.rc1, same issue, no friendly_id

@jeremy
Copy link
Member

jeremy commented May 23, 2016

This is due to initialization order. Any plugin that loads AR will cause it to pull config to AR::Base so subsequent initializers will be too late in the game to take effect.

Try setting this in config/application.rb instead or setting ActiveRecord::Base.belongs_to_required_by_default = true instead of Rails.application.config.active_record.belongs_to_required_by_default.

@arokettu
Copy link

@jeremy thanks! But default rails initializer should be changed accordingly then so it won't confuse people in this situation

@jeremy
Copy link
Member

jeremy commented May 23, 2016

Agree @sandfoxme. Up for submitting a PR?

@arokettu
Copy link

@jeremy ok, maybe tomorrow

@arokettu
Copy link

Actually I'm confused on how to fix this. Just changing initializer to ActiveRecord::Base.belongs_to_required_by_default = true seems not good enough

p.s. and the issue should be reopened

@lleger
Copy link
Contributor

lleger commented Jun 23, 2016

This issue bit me today after upgrading to RC2. Setting ActiveRecord::Base.belongs_to_required_by_default solved the issue for me. When I upgraded, I removed config/initializers/active_record_belongs_to_required_by_default.rb in favor of config/initializers/new_framework_defaults.rb. Adding that file back and simply setting Rails.application.config.active_record.belongs_to_required_by_default also solved the issue. In my mind that supports the "initialization order" issue. Happy to work on a PR to help this if anyone has thoughts on where to start.

@lleger
Copy link
Contributor

lleger commented Jun 23, 2016

In my case, specifically, it seems like the Devise initializer caused the issue. Moving it to the bottom of the order (z_devise.rb) alleviated the issue.

@rafaelfranca
Copy link
Member

While I agree that we can fix this issue it is more a plugin/gem not playing nice with the rails hooks. I'll take care of fixing it in devise and if you can try to find which gem/plugin is doing it please open an issue.

@lukeredpath
Copy link
Contributor

lukeredpath commented Jun 24, 2016

Also ran into this issue (I think its this issue) when installing the paranoia gem:
rubysherpas/paranoia#335

Narrowed it down to the fact that it is re-opening ActiveRecord::Base.

I suppose the question is where should this issue be fixed? Should gems not being re-opening ActiveRecord::Base? Should this be fixed in Rails?

I only picked this up because my specs for required behaviour stopped passing after I installed the gem (pro-tip: always write specs for important behaviour even if the framework does it by default).

You can reproduce this behaviour by simply re-opening ActiveRecord after loading Rails but before loading gems:

# application.rb
require 'rails/all'

class ActiveRecord::Base
end

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

@lukeredpath
Copy link
Contributor

My current preferred workaround for this issue, if caused by a gem, is to disable auto-require in your Gemfile:

gem 'paranoia', require: false

Create a new initialiser in which you require any libraries that re-open ActiveRecord

# z_paranoia.rb
require 'paranoia'

This ensures that it gets loaded after the configuration is set.

@rafaelfranca
Copy link
Member

I suppose the question is where should this issue be fixed? Should gems not being re-opening ActiveRecord::Base? Should this be fixed in Rails?

This should be fixed in the gems.

There is no problem in re-opening ActiveRecord::Base but they need to do in the right way.

See heartcombo/devise@c2c74b0 on how they should be doing this.

@arokettu
Copy link

Many gems re-open ActiveRecord::Base so I think there should be at least bad behavior detection with a warning, otherwise we have incorrect state without any clear sign of it

@wlipa
Copy link

wlipa commented Aug 12, 2016

Should we not refer to model classes in initializers (to reference constants, e.g.)? Doing so in an early initializer seems to break active_record_belongs_to_required_by_default as well.

@rafaelfranca
Copy link
Member

Should we not refer to model classes in initializers (to reference constants, e.g.)?

It is not recommended, no. This not just breaking the hooks but also can connect to database when you should not be connecting.

@rafaelfranca
Copy link
Member

I think there should be at least bad behavior detection with a warning, otherwise we have incorrect state without any clear sign of it

👍. This is something that we should have. If you want please submit a pull request.

I'm closing since this is no much we can do here.

@george-carlin
Copy link
Contributor

Reposting my comment from #27844 just in case anyone here might find it helpful:


If anyone else is having this same issue, I "fixed" it by removing the active_record_belongs_to_required_by_default.rb initializer and adding the line self.belongs_to_required_by_default = true to my ApplicationRecord.

Really, this fixes the symptom rather than the problem - I'm not sure what's causing the initializer to not be loaded probably; it's probably one of my gems. But the above hack is good enough for now.

yahonda added a commit to yahonda/oracle-enhanced that referenced this issue Oct 30, 2017
milk1000cc added a commit to milk1000cc/acts_as_digested_on that referenced this issue Dec 15, 2017
Use AS.on_load to avoid setting AR consts before config loaded.
It fixes `belongs_to_required_by_default` config behaviour disscussed
in rails/rails#23589
davegson added a commit to safing/stamp.community that referenced this issue May 8, 2018
It is not really clear what settings are changed… But an assumption
would be: Coursemology/coursemology2#2632

They introduced it in here: rails/rails#23589
louim added a commit to didacte/hstore_translate that referenced this issue May 28, 2018
p8 added a commit to mdh/ssm that referenced this issue Jul 7, 2019
ActiveRecord should not be loaded in other gems or initializers.
Instead we should use the on_load hook.
rails/rails#23589
@p8
Copy link
Member

p8 commented Jul 8, 2019

To find out which gem is calling ActiveRecord before Rails has initialized, add the following line to config/application.rb before Bundler.require(*Rails.groups):

  ::ActiveRecord = 1

@akostadinov
Copy link
Contributor

To figure out where issue comes from, better follow advice in #39855 (comment) and similar for ActiveJob #37030 (comment)

Basically ActiveSupport.on_load(:active_job) { puts caller } and possibly some puts calls to see at which point some particular initializer is being executed.

DannyMay9082 added a commit to DannyMay9082/ransack that referenced this issue Feb 16, 2023
For avoiding autoloading these constants too soon.
This affect the initialization of Active Record.
Ref: rails/rails#23589 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests